package com.atguigu.java8.streamDemo;

import com.atguigu.java8.lambdaDemo.Employee;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Xiaohong X Gou
 * @createTime 2022-10-12 09:38
 * @description
 *
 * 终止操作
 */
public class TestStreamAPI3 {
    /*
        查找与匹配
        allMatch:检查是否匹配所有元素
        anyMatch:检查是否匹配至少一个元素
        noneMatch:检查是否没有匹配所有元素
        findFirst:返回第一个元素
        findAny:返回当前流中的任意元素
        count:返回流中元素的总个数
        max:返回流中最大值
        min:返回流中最小值
     */
    List<Employee> employees = Arrays.asList(
            new Employee(1,"张三",18,9999.99, Employee.Status.FREE),
            new Employee(2,"李四",38,5555.99, Employee.Status.BUSY),
            new Employee(3,"王五",50,6666.66, Employee.Status.VOCATION),
            new Employee(4,"赵六",16,3333.33, Employee.Status.FREE),
            new Employee(5,"田七",12,8888.88, Employee.Status.BUSY)
    );
    @Test
    public void test1(){
        boolean b = employees.parallelStream()
                .allMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b);

        boolean b1 = employees.stream()
                .anyMatch(e -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b1);

        boolean b2 = employees.stream()
                .noneMatch(e -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b2);

        Optional<Employee> first = employees.stream()
                .sorted((e1, e2) -> -Double.compare(e1.getSalary(), e2.getSalary()))
                .findFirst();
        System.out.println(first.get());

        Optional<Employee> any = employees.stream()
                .filter(e -> e.getStatus().equals(Employee.Status.FREE))
                .findAny();
        System.out.println(any);
    }
    @Test
    public void test2(){
        long count = employees.stream()
                .count();
        System.out.println(count);

        Optional<Employee> max = employees.stream()
                .max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        System.out.println(max);

        Optional<Double> min = employees.stream()
                .map(Employee::getSalary)
                .min(Double::compare);
        System.out.println(min);
    }
    /*
      归约
      reduce(T identity,BinaryOperator) / reduce(BinaryOperator):可以将流中元素反复结合起来，得到一个值。
    */
    @Test
    public void test3(){
        List<Integer> list=Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        Integer reduce = list.stream()
                .reduce(0, (x, y) -> x + y);
        System.out.println(reduce);

        Optional<Double> reduce1 = employees.stream()
                .map(Employee::getSalary)
                .reduce(Double::sum);
        System.out.println(reduce1.get());
    }
    /*
        收集
        collect:将流转换为其他形式。接收一个Collector接口的实现，用于给stream中元素做汇总的方法
     */
    @Test
    public void test4(){
        List<String> collect = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toList());
        collect.forEach(System.out::println);

        System.out.println("...................");
        Set<String> collect1 = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toSet());
        collect1.forEach(System.out::println);

        System.out.println("...........................");
        HashSet<String> collect2 = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toCollection(HashSet::new));
        collect2.forEach(System.out::println);
    }
    @Test
    public void test5(){
        Long collect = employees.stream()
                .collect(Collectors.counting());
        System.out.println(collect);

        Double collect1 = employees.stream()
                .collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println(collect1);

        Double collect2 = employees.stream()
                .collect(Collectors.summingDouble(Employee::getSalary));
        System.out.println(collect2);

        Optional<Employee> collect3 = employees.stream()
                .collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
        System.out.println(collect3.get());

        Optional<Double> collect4 = employees.stream()
                .map(Employee::getSalary)
                .collect(Collectors.minBy(Double::compare));
        System.out.println(collect4);
    }
    @Test
    public void test6(){
        System.out.println(employees.stream()
                .collect(Collectors.groupingBy(Employee::getStatus)));
    }
    @Test
    public void test7(){
        Map<Employee.Status, Map<String, List<Employee>>> collect = employees.stream()
                .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(e -> {
                    if (e.getAge() <= 35) {
                        return "青年";
                    } else if (e.getAge() <= 50) {
                        return "中年";
                    } else {
                        return "老年";
                    }
                })));
        System.out.println(collect);

    }
    @Test
    public void test8(){
        Map<Boolean, List<Employee>> collect = employees.stream()
                .collect(Collectors.partitioningBy((e) -> e.getSalary() > 8000));
        System.out.println(collect);
    }
    @Test
    public void test9(){
        DoubleSummaryStatistics collect = employees.stream()
                .collect(Collectors.summarizingDouble(Employee::getSalary));
        System.out.println(collect);
    }
    @Test
    public void test10(){
        String collect = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.joining(",","===","==="));
        System.out.println(collect);
    }
}
